If we want multi kenal level thread
started with a large PCB structure, and divide the information across a number of different data structure.
Cons:
Sun OS 5.0 Trheading model
Process:
Light weight process (LWP) data structures, containing information that are relavent for the subset of the process
Kernal-level threads:
CPU:
Assume process requests 2 kernel level threads. What happens whe nprocess starts?
0:underlying manager should decide how to manage concurrency level for the particular process.
UL library sees
Kernel sees:
User level library can request one of its user level threads be bond to to KLT
Thread pinning: If a KTL is permanently associated with a CPU Bound thread: 1:1 ULT and KTL bound
Problem: visibilty of state and decisions between kernel and UL libray, if KLTs are locked no ULTs can run even they are ready.
Invisible to kernel: mutex vaiable wait queues
Many to many:
1-1 helps address some of these issues.
Process jumps to UL library scheduler when
One CPU can't modify another cpu's register, so we have to send signal from the context of one KLT on one CPU to another KLT on the other CPU to run library code locally.
ULTs different CPUs wants mutex: put on a mutex queue then context switch
Interrups:
Signals:
Simillar
They can be
An external device send notification (MSI#) to a CPU via interconnect (PCI) between the device and CPU complex.
Synchronoous
Asynchronous
When interrupt
To sovle the problem:
clear_field_in_mask(mask);
lock(mutex);
//disabled => remain pending
unlock(mutex);
reset_field_in_mask(mask);
//enabled => execute handler code.
Intrerupt masks are per CPU. If mask disableds interrupt => hardware interrupt routing mechanism will not deliver interrupt to cpu.
Signal masks are per execution context (ULT on top of KLT). If mask disables signal=>kernel sees mask and will not interrupt corresponding thread.
One-shot signals:
Real time signals
Overall Cost
If ULT disable signal mask but KLT enable the signal. Signal occurs, what to do with the signal?
//Task struct in Linux
struct task_struct {
pid_t pid; //task id
pid_t tgid; //group id, the first created task id in the group
int prio;
volatile long state;
struct mm_struct *mm;
struct files_struct *files;
struct list_head tasks; // the list of tasks which are part of a single process
int on_cpu;
cpumask_t cpu_allowed;
//...
}
// process state was always represented by a collection of reference or pointers to data structures. So it's easier for tasks in a single process to share.
clone(function, stack_ptr, sharing_flags, args)
sharing_flags: which portion of the state of a task will be shared between the parent and child task.
Forking:
Current: Native POSIX Threads Library (NPTL) "1:1 model": one kernel level task for each ULT.
Older Linux Threads "M-M model" - similar issues to those described in Solaris papers. May fit for some more complicated situation.
Sun/Solaris papers
Interrupts and signals